<template>
  <div class='container'>
    <div :id='propId' ref='echarts' style='width: 100%; height: 100% '/>
  </div>
</template>

<script>
/*eslint-disable*/

// 引入基本模板
let echarts = require('echarts/lib/echarts')

require('echarts/theme/macarons.js')
require('echarts/theme/dark.js')
require('echarts/lib/chart/line')
require('echarts/lib/chart/bar')
require('echarts/lib/chart/pie')

// 引入提示框和title组件
require('echarts/lib/component/tooltip')
require('echarts/lib/component/title')

require('echarts/lib/component/legend')
require('echarts/lib/component/legendScroll')
require('echarts/lib/component/toolbox')

export default {
  data() {
    return {
      chartModel: {
        config: {},
        chartFields: [],          // 图表配置字段
        gridFields: [],    // 表格配置字段
        data: []
      },
      chart: null
    }
  },
  methods: {
    fetchData() {
      if (this.strings.isBlank(this.propReportKey)) {
        return
      }
      let params = this.propParams || {}
      let url = `/report/config/fetchData?reportKey=${this.propReportKey}`
      this.$ajax.get(url, {
        params
      }).then(resp => {
        this.chartModel = resp.data
        this.drawChart()
      })
    },
    drawLineBar() {
      let title = this.chartModel.config.name
      let xAxis = this.chartModel.chartFields.filter(o => o.axis.toLowerCase() == 'X'.toLowerCase()).map(o => {
        return {
          type: 'category',
          data: this.chartModel.data.map(item => item[o.labelField]),
          axisLabel: {
            // interval: 0,//横轴信息全部显示
            // rotate: -15,//-15度角倾斜显示
            fontSize: this.propFontSize,
            formatter: this._axisLabelFormatter
          },
          axisPointer: {
            type: 'shadow'
          }
        }
      })
      if (xAxis == null || xAxis.length == 0) {
        this.utilMessage.error('X轴坐标未设置值')
        return
      }

      let yAxis = this.chartModel.chartFields.filter(o => o.axis.toLowerCase() == 'Y'.toLowerCase()).map(o => {
        return {
          name: o.legend,
          type: 'value',
          axisLabel: {
            fontSize: this.propFontSize
          }
        }
      })

      if (yAxis == null || yAxis.length == 0) {
        yAxis = {
          type: 'value',
          axisLabel: {
            fontSize: this.propFontSize
          },
        }
      }

      let legend = {
        data: this.chartModel.chartFields.map(o => o.legend),
        bottom: 'left',
        y: 'top'
      }

      let series = this.chartModel.chartFields.filter(o => o.flagSeries).map(o => {
        return {
          name: o.legend,
          type: o.seriesType,
          data: this.getSeriesDataMethod(this.chartModel.data, o.labelField, o.valueField),
          stack: this.strings.isBlank(o.stack) ? null : o.stack,
          itemStyle: { normal: { label: { show: true, position: 'top', textStyle: { propFontSize: this.propFontSize }} } },
          label: {
            normal: {
              show: true,
              textStyle: {
                fontSize: this.propFontSize
              }
            },
            emphasis: {
              show: true
            }
          }
        }
      })

      let options = {
        // title: { text: title},
        textStyle: {
          fontSize: this.propFontSize
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'cross',
            crossStyle: {
              color: '#999'
            }
          },
          textStyle: {
            fontSize: this.propFontSize
          },
        },
        toolbox: {
          show: false,
          feature: {
            magicType: { show: true, type: ['line', 'bar'] },
            restore: { show: true },
            saveAsImage: { show: true }
          }
        },
        legend,
        xAxis,
        yAxis,
        series,
      }
      this.utils.mergeDeep(options, this.propOptions)
      // 绘制图表
      this.chart.setOption(options)
    },
    drawPie() {
      let len = this.chartModel.chartFields.filter(o => o.seriesType == 'pie').length
      if (len != 1) {
        // 如果有多个字段，另外处理
        return
      }
      let field = this.chartModel.chartFields.filter(o => o.seriesType == 'pie')[0]

      let title = this.chartModel.config.chartName
      let options = {
        title: {
          top: 20,
          textStyle: {
            color: '#ccc'
          }
        },
        grid: {
          left: '5%',
          right: '5%'
        },
        textStyle: {
          fontSize: this.propFontSize
        },
        tooltip: {
          textStyle: {
            fontSize: this.propFontSize
          },
          trigger: 'item',
          formatter: '{a} <br/>{b} : {c} ({d}%)'
        },

        legend: {
          bottom: 10,
          left: 'center',
          y: 'top',
          data: this.chartModel.data.map(item => {
            return item[field.labelField]
          })
        },
        series: [
          {
            name: field.legend,
            type: 'pie',
            radius: '55%',
            center: ['50%', '50%'],
            data: this.chartModel.data.map(item => {
              return {
                value: item[field.valueField],
                name: item[field.labelField]
              }
            }).sort((a, b) => { return a.value - b.value }),

            itemStyle: {
              emphasis: {
                shadowBlur: 10,
                shadowOffsetX: 0,
                shadowColor: 'rgba(0, 0, 0, 0.5)'
              }
            },
          }
        ]
      }
      this.utils.mergeDeep(options, this.propOptions)
      // 绘制图表
      this.chart.setOption(options)
    },
    drawGauge() {
      // 仪表盘
      let series = this.chartModel.chartFields.filter(o => o.flagSeries).map(o => {
        return {
          name: o.legend,
          type: 'gauge',
          data: this.chartModel.data.map(item => {
            return {
              value: item[o.valueField]
            }
          })
        }
      })

      let options = {
        tooltip: {
          formatter: '{a} <br/>{b} : {c}%'
        },
        toolbox: {},
        series
      }

      this.utils.mergeDeep(options, this.propOptions)
      // 绘制图表
      this.chart.setOption(options)
    },
    drawChart() {
      // 基于准备好的dom，初始化echarts实例
      let dom = document.getElementById(this.propId)
      if (dom == null) {
        return
      }
      this.reset()
      // macarons dark
      this.chart = echarts.init(dom, this.strings.defaultIfBlank(this.propTheme, 'macarons'), this.cpInitOptions)
      let chartType = this.cpChartType
      switch (chartType) {
      case 'line':
        this.drawLineBar()
        break
      case 'bar':
        this.drawLineBar()
        break
      case 'pie':
        this.drawPie()
        break
      case 'gauge':
        this.drawGauge()
        break
      default:
        this.utilMessage.error('未实现的图表功能')
      }
      this.chart.resize()

      // removeResizeListener(window.document.body, resizeListener)
      // addResizeListener(window.document.body, resizeListener)
    },
    reset() {
      if (!this.chart) {
        return
      }
      this.chart.dispose()
      this.chart = null
    },

    _axisLabelFormatter(value) {
      let maxLength = this.propXAxisLabelLengthPerRow //每项显示文字个数
      if (maxLength == null || maxLength <= 0) {
        return value
      }

      let ret = '' //拼接加\n返回的类目项

      let valLength = value.length //X轴类目项的文字个数
      let rowN = Math.ceil(valLength / maxLength) //类目项需要换行的行数
      if (rowN > 1) {
        // 如果类目项的文字大于1,
        for (let i = 0; i < rowN; i += 1) {
          let temp = ''//每次截取的字符串
          let start = i * maxLength//开始截取的位置
          let end = start + maxLength//结束截取的位置
          //这里也可以加一个是否是最后一行的判断，但是不加也没有影响，那就不加吧
          temp = value.substring(start, end) + '\n'
          ret += temp //凭借最终的字符串
        }
        return ret
      }
      return value
    },
  },
  created() {
    this.fetchData()
  },
  components: {

  },
  computed: {
    cpChartType() {
      let {config} = this.chartModel
      return config ? config.type : null
    },
    cpInitOptions() {
      let options = {}
      if (this.strings.isNotBlank(this.propHeight)) {
        options.height = this.propHeight
      }
      if (this.strings.isNotBlank(this.propWidth)) {
        options.width = this.propWidth
      }
      return options
    }
  },
  props: {
    propReportKey: {
      type: String,
      required: true
    },
    propId: {
      type: String,
      default: () => `${parseInt(Math.random() * 10000, 10)}`
    },
    propFontSize: {
      type: Number,
      default: () => {
        return 18
      }
    },
    propHeight: {
      type: [String, Number],
      default: () => 400
    },
    propWidth: {
      type: [String, Number],
      default: () => '100%'
    },
    propTheme: {
      type: [String],
      // 主题. 可取值: default、macarons、dark
      default: () => 'macarons'
    },
    propXAxisLabelLengthPerRow: {
      type: [Number],
      default: () => null
    },
    propOptions: {},
    propParams: {}, // 查询参数
    /**
     * 获取Series Data的方法
     * @param  data  数据
     * @param  labelField 标签字段名
     * @param valueField 值字段名称
     * @returns Array
     *
     */
    getSeriesDataMethod: {
      type: Function,
      default: (data, labelField, valueField) => {
        return data.map(item => item[valueField])
      }
    }
  }
}
</script>

<style lang='scss' scoped>
  .container {
    width: 100%;
    height: 100%;
  }
</style>
